﻿using System;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;

using SimbaRGVMonitor.Common.Linq;

namespace SimbaRGVMonitor.Common.Diagnostics
{
    public sealed class MonitorLoggerPool
    {
        public MonitorLoggerPool()
        {
            InitializeSettings();
        }

        //====================================================================================================
        //以上是类型构造函数
        //----------------------------------------------------------------------------------------------------
        //以下是类型字段
        //====================================================================================================

        private bool enable = true;
        private const string configName = "Log4Net.config";
        private readonly object syncThreadLock = new object();
        private readonly Dictionary<string, MonitorLogger> currentLoggers = new Dictionary<string, MonitorLogger>();

        public bool Enable
        {
            get { return enable; }
            set
            {
                if (enable != value)
                {
                    lock (syncThreadLock)
                    {
                        enable = value;
                        foreach (var logger in currentLoggers.Values)
                        {
                            logger.Enable = value;
                        }
                    }
                }
            }
        }

        //====================================================================================================
        //以上是类型字段
        //----------------------------------------------------------------------------------------------------
        //以下是类型事件及触发函数
        //====================================================================================================

        public event EventHandler<MonitorLoggerWritedEventArgs> LogWrited;
        private void OnLogWrited(object sender, MonitorLoggerWritedEventArgs e)
        {
            LogWrited.TriggerEvent(this, e);
        }

        //====================================================================================================
        //以上是类型事件及触发函数
        //----------------------------------------------------------------------------------------------------
        //以下是初始化设置
        //====================================================================================================

        private void InitializeSettings()
        {
            var path = Application.StartupPath;
            var filePath = Path.Combine(path, configName);
            if (File.Exists(filePath) == false)
            {
                var message = string.Format("路径{0}下，缺少配置文件{1}", path, configName);
                throw new InvalidOperationException(message);
            }

            var fileInfo = new FileInfo(filePath);
            log4net.Config.XmlConfigurator.ConfigureAndWatch(fileInfo);
        }

        //====================================================================================================
        //以上是初始化设置
        //----------------------------------------------------------------------------------------------------
        //以下是获取日志
        //====================================================================================================

        public MonitorLogger GetLogger(string name)
        {
            lock (syncThreadLock)
            {
                MonitorLogger customLogger;
                var iLog = log4net.LogManager.Exists(name);
                if (iLog != null && currentLoggers.TryGetValue(name, out customLogger))
                {
                    customLogger = currentLoggers[name];
                }
                else if (iLog == null && currentLoggers.TryGetValue(name, out customLogger) == false)
                {
                    iLog = log4net.LogManager.GetLogger(name);
                    customLogger = new MonitorLogger(name, iLog);
                    customLogger.Enable = enable;
                    customLogger.LogWrited += OnLogWrited;
                    currentLoggers.Add(name, customLogger);
                }
                else
                {
                    var message = string.Format("获取日志{0}失败", name);
                    throw new InvalidOperationException(message);
                }
                return customLogger;
            }
        }
    }
}
